import * as THREE from "three";
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
//引入性能监视器stats.js
import Stats from 'three/addons/libs/stats.module.js';

const stats = new Stats()

// stats.domElement显示：渲染帧率  刷新频率,一秒渲染次数 
// stats.setMode(0);//默认模式
//stats.domElement显示：渲染周期 渲染一帧多长时间(单位：毫秒ms)
stats.setMode(1);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// ------------------------------------------------ 
// p1、p2、p3表示三个点坐标
// p1、p3是曲线起始点，p2是曲线的控制点
// const p1 = new THREE.Vector2(-80, 0);
// const p2 = new THREE.Vector2(20, 100);
// const p3 = new THREE.Vector2(80, 0);

// 二维二次贝赛尔曲线
// const curve = new THREE.QuadraticBezierCurve(p1, p2, p3);

// p1、p2、p3表示三个点坐标
// const p1 = new THREE.Vector3(-80, 0, 0);
// const p2 = new THREE.Vector3(20, 100, 0);
// const p3 = new THREE.Vector3(80, 0, 100);
// // 三维二次贝赛尔曲线
// const curve = new THREE.QuadraticBezierCurve3(p1, p2, p3);


// p1、p2、p3、p4表示4个点坐标
// p1、p4是曲线起始点，p2、p3是曲线的控制点
// const p1 = new THREE.Vector2(-80, 0);
// const p2 = new THREE.Vector2(-40, 50);
// const p3 = new THREE.Vector2(50, 50);
// const p4 = new THREE.Vector2(80, 0);

// // 二维三次贝赛尔曲线
// const curve = new THREE.CubicBezierCurve(p1, p2, p3, p4);

// const p1 = new THREE.Vector3(-80, 0, 0);
// const p2 = new THREE.Vector3(-40, 50, 0);
// const p3 = new THREE.Vector3(50, 50, 0);
// const p4 = new THREE.Vector3(80, 0, 100);
// // 三维三次贝赛尔曲线
// const curve = new THREE.CubicBezierCurve3(p1, p2, p3, p4);

// 三维样条曲线CatmullRomCurve3实现飞线轨迹
// p1、p3轨迹线起始点坐标
// const p1 = new THREE.Vector3(-100, 0, -100);
// const p3 = new THREE.Vector3(100, 0, 100);
// // 计算p1和p3的中点坐标
// const x2 = (p1.x + p3.x)/2;
// const z2 = (p1.z + p3.z)/2;
// const h = 50;
// const p2 = new THREE.Vector3(x2, h, z2);

// const arr = [p1, p2, p3];
// // 三维样条曲线
// const curve = new THREE.CatmullRomCurve3(arr);


// 三维二次贝赛尔曲线QuadraticBezierCurve3实现飞线轨迹
// p1、p3轨迹线起始点坐标
// const p1 = new THREE.Vector3(-100, 0, -100);
// const p3 = new THREE.Vector3(100, 0, 100);
// // 计算p1和p3的中点坐标
// const x2 = (p1.x + p3.x)/2;
// const z2 = (p1.z + p3.z)/2;
// const h = 100;
// const p2 = new THREE.Vector3(x2, h, z2);
// // 三维二次贝赛尔曲线
// const curve = new THREE.QuadraticBezierCurve3(p1, p2, p3);

// 组合曲线CurvePath拼接曲线
// 3D直线LineCurve3和2D直线LineCurve
// new THREE.LineCurve3(new THREE.Vector3(), new THREE.Vector3());
// new THREE.LineCurve(new THREE.Vector2(), new THREE.Vector2());

const R = 50;//圆弧半径
const H = 100;//直线部分高度
// 直线1
const line1 = new THREE.LineCurve(new THREE.Vector2(R, H), new THREE.Vector2(R, 0));
// 圆弧
const arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
// 直线2
const line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0), new THREE.Vector2(-R, H));

// CurvePath创建一个组合曲线对象
const CurvePath = new THREE.CurvePath();
//line1, arc, line2拼接出来一个U型轮廓曲线，注意顺序
CurvePath.curves.push(line1, arc, line2);

const pointsArr2 = CurvePath.getSpacedPoints(16); //曲线上获取点
const geometry2 = new THREE.BufferGeometry();
geometry2.setFromPoints(pointsArr2); //读取坐标数据赋值给几何体顶点

// 可视化curve.getPoints从曲线上获取的点坐标
const material2 = new THREE.PointsMaterial({
    color: 0xff00ff,
    size: 10,
});
//点模型对象
const points = new THREE.Points(geometry2, material2);

scene.add(points)


// 曲线上获取一定数量点，线模型line渲染贝塞尔曲线。
const pointsArr = CurvePath.getPoints(100); //曲线上获取点
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints(pointsArr); //读取坐标数据赋值给几何体顶点
const material = new THREE.LineBasicMaterial({color: 0x00fffff});
const line = new THREE.Line(geometry, material);

scene.add(line)
// -----------------------------------------------
// 设置相机的位置以便更好地查看线段
camera.position.z = 200;
camera.position.y = 200;
camera.position.x = 200;
// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}
animate();


const axesHelper = new THREE.AxesHelper(150);

// 添加辅助坐标系
scene.add(axesHelper);

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
// const width = window.innerWidth; //窗口文档显示区的宽度作为画布宽度
// const height = window.innerHeight; //窗口文档显示区的高度作为画布高度



//点光源：两个参数分别表示光源颜色和光照强度
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 1.0; //设置光源距离衰减

// 你可以对比不同光照强度明暗差异(传播同样距离)
pointLight.intensity = 100.0; //光照强度
// pointLight.intensity = 50000.0;//光照强度

//点光源位置 ,放在x轴上
// pointLight.position.set(0, 400, 400);
// pointLight.position.set(100, 60, 50);
pointLight.position.set(100, 50, 75);

//点光源添加到场景中
// scene.add(pointLight);

// 光源辅助观察
// const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
// scene.add(pointLightHelper);

//环境光:没有特定方向，整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambient);

// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向：通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// directionalLight.position.set(100, 0, 0);
// directionalLight.position.set(0, 100, 0);
// directionalLight.position.set(100, 100, 100);
// directionalLight.position.set(100, 60, 50);
// 方向光指向对象网格模型mesh，可以不设置，默认的位置是0,0,0
// directionalLight.target = mesh;
// scene.add(directionalLight);

// DirectionalLightHelper：可视化平行光
// const dirLightHelper = new THREE.DirectionalLightHelper(
//   directionalLight,
//   5,
//   0xff0000
// );
// scene.add(dirLightHelper);


// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 启用阻尼效果
controls.enableDamping = true;
controls.dampingFactor = 0.05;

// 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
controls.addEventListener("change", function () {
  renderer.render(scene, camera); //执行渲染操作
  // 浏览器控制台查看相机位置变化
  // console.log("camera.position", camera.position);
});

//执行渲染操作
renderer.render(scene, camera);



// Canvas画布插入到任意HTML元素中
// document.getElementById("webgl").appendChild(renderer.domElement);

document.body.appendChild(renderer.domElement);
document.body.appendChild(stats.domElement)



// 渲染函数
function render() {
  renderer.render(scene, camera); //执行渲染操作
  // mesh.rotateY(0.01); //每次绕y轴旋转0.01弧度
  controls.update(); // 必须调用此方法，以便阻尼效果生效
  stats.update(); //requestAnimationFrame循环调用的函数中调用方法update(),来刷新时间
  requestAnimationFrame(render); //请求再次执行渲染函数render，渲染下一帧
}
render();

window.onresize = function () {
  // 重置渲染器输出画布canvas尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 全屏情况下：设置观察范围长宽比aspect为窗口宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
  // 但是不会每渲染一帧，就通过相机的属性计算投影矩阵(节约计算资源)
  // 如果相机的一些属性发生了变化，需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
  camera.updateProjectionMatrix();
};

// console.log(THREE);
